package cn.hennancf.qieqie.utils.http;

import com.alibaba.fastjson.JSON;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 *
 * @Description httpsPost请求类
 * @author jiang_kun@suixingpay.com
 * @date 2016年10月12日 下午2:54:47
 */
public class HttpsPost {

	private static final Logger logger = LoggerFactory.getLogger(HttpsPost.class);

	private final static String CHARACTER_SET = "UTF-8";

	private final static String APPLICATION_JSON = "application/json";

	/**
	 * @Title post 
	 * @Description 请求方法
	 * @param url 
	 * @param params
	 * @param timeout
	 * @param characterSet
	 * @return HttpSendResult
	 */
	public static HttpSendResult post(String url, Map<String, String> params, int timeout, String characterSet) {
		if (characterSet == null || "".equals(characterSet)) {
			characterSet = "UTF-8";
		}
		HttpSendResult result = new HttpSendResult();

		SSLConnectionSocketFactory sslsf = null;
		try {
			sslsf = getSSLConnectionSocketFactory();
		} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e1) {
			logger.error("鉴权接口调用异常 SSL创建异常", e1);
			return result;
		}
		CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build();

		HttpPost httpPost = new HttpPost(url);
//		httpPost.setHeader("Connection", "close");
		httpPost.addHeader("Content-Type", "application/json" );

		httpPost.setConfig(config);
		// 建立一个NameValuePair数组，用于存储欲传送的参数
		List<NameValuePair> postParam = new ArrayList<NameValuePair>();
		for (String key : params.keySet()) {
			postParam.add(new BasicNameValuePair(key, params.get(key)));
		}
		// 添加参数
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(postParam, characterSet));
		} catch (UnsupportedEncodingException e1) {
			logger.error("鉴权接口调用异常 参数异常", e1);
			return result;
		}

		CloseableHttpResponse resp = null;
		try {
			resp = client.execute(httpPost);
			result.setStatus(resp.getStatusLine().getStatusCode());
			result.setResponseBody(EntityUtils.toString(resp.getEntity(), characterSet));
		} catch (IOException | ParseException e) {
			logger.error("鉴权接口调用异常", e);
			return result;
		} finally {
			if (resp != null) {
				try {
					resp.close();
				} catch (IOException e2) {
					logger.error("关闭HTTPCLIENT输出流异常", e2);
				}
			}
		}

		return result;
	}

	
	
	public static HttpSendResult post0(String url, Map<String, String> params, int timeout,String contentType, String characterSet) {
		if (characterSet == null || "".equals(characterSet)) {
			characterSet = "UTF-8";
		}
		HttpSendResult result = new HttpSendResult();

		SSLConnectionSocketFactory sslsf = null;
		try {
			sslsf = getSSLConnectionSocketFactory();
		} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e1) {
			logger.error("鉴权接口调用异常 SSL创建异常", e1);
			return result;
		}
		CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build();

		HttpPost httpPost = new HttpPost(url);
		httpPost.setHeader("Connection", "close");
		httpPost.addHeader("Content-Type", contentType+";charset=" + characterSet);

		httpPost.setConfig(config);
		// 建立一个NameValuePair数组，用于存储欲传送的参数
		List<NameValuePair> postParam = new ArrayList<NameValuePair>();
		for (String key : params.keySet()) {
			postParam.add(new BasicNameValuePair(key, params.get(key)));
		}
		// 添加参数
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(postParam, characterSet));
		} catch (Exception e1) {
			logger.error("鉴权接口调用异常 参数异常", e1);
			return result;
		}

		CloseableHttpResponse resp = null;
		try {
			resp = client.execute(httpPost);
			result.setStatus(resp.getStatusLine().getStatusCode());
			result.setResponseBody(EntityUtils.toString(resp.getEntity(), characterSet));
		} catch (IOException | ParseException e) {
			logger.error("鉴权接口调用异常", e);
			return result;
		} finally {
			if (resp != null) {
				try {
					resp.close();
				} catch (IOException e2) {
					logger.error("关闭HTTPCLIENT输出流异常", e2);
				}
			}
		}

		return result;
	}
	
	
	/**
	 * 该请求使用的参数，内部会转成json串，然后将json串作为整体参数提传递请求
	 * @param url
	 * @param params
	 * @param timeout
	 * @return
	 */
	public static HttpSendResult postJsonParam(String url, Map<String, Object> params, int timeout,Map<String,String> header) {
		HttpSendResult result = new HttpSendResult();

		SSLConnectionSocketFactory sslConnectionSocketFactory;
		try {
			sslConnectionSocketFactory = getSSLConnectionSocketFactory();
		} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e1) {
			logger.error("鉴权接口调用异常 SSL创建异常", e1);
			return result;
		}
		CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
		RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build();

		HttpPost httpPost = new HttpPost(url);

		header.keySet().stream().forEach(p->httpPost.addHeader(p,header.get(p)));


		httpPost.setConfig(config);
		String requestJson = JSON.toJSONString(params) ;
		logger.info("requestJson :{}",requestJson);
		StringEntity req =  new StringEntity(requestJson, ContentType.create(APPLICATION_JSON, CHARACTER_SET));
		// 添加参数
		try {
			httpPost.setEntity(req);
		} catch (Exception e1) {
			logger.error("鉴权接口调用异常 参数异常", e1);
			return result;
		}

		CloseableHttpResponse resp = null;
		try {

			resp = client.execute(httpPost);
			result.setStatus(resp.getStatusLine().getStatusCode());
			result.setResponseBody(EntityUtils.toString(resp.getEntity(), CHARACTER_SET));
		} catch (IOException | ParseException e) {
			logger.error("鉴权接口调用异常", e);
			return result;
		} finally {
			if (resp != null) {
				try {
					resp.close();
				} catch (IOException e2) {
					logger.error("关闭HTTPCLIENT输出流异常", e2);
				}
			}
		}

		return result;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	/**
	 * @Title getSSLConnectionSocketFactory
	 * @Description 创建没有证书的SSL链接工厂类
	 * @throws NoSuchAlgorithmException
	 * @throws KeyStoreException
	 * @throws KeyManagementException
	 * @return SSLConnectionSocketFactory
	 */
	public static SSLConnectionSocketFactory getSSLConnectionSocketFactory()
			throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
		SSLContextBuilder context = new SSLContextBuilder();
		context.loadTrustMaterial(null, new TrustStrategy() {
			@Override
			public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				return true;
			}
		});
		return new SSLConnectionSocketFactory(context.build());
	}
}